#include "../../../socket/internal/IoPortService.h"
#include "../../../socket/TcpIoServer.h"
#include "../../../socket/TcpIoSocket.h"
#include "../../../socket/Timer.h"
#include "../../../stream/StringTools.h"
#include "../ClassFactory.h"
#include "Service.h"
#include "Client.h"
#include <vector>

DEF_BEG_LIBTOOLS

Service::Service() : _config(new TcpConfig), _mgr(new  CSafeMap<SOCKIDEN, SharedPtr<Client> >()), _isServer(true)
{
}

Service::~Service()
{
	if (_mgr) delete _mgr;
	_mgr = NullPtr;
}

// void Service::DeleteClient(Client* c)
// {
// 	_mgr->Erase(c->GetSocketIden());
// }

void Service::DeleteClient(SOCKIDEN id)
{
	_mgr->Erase(id);
}

bool Service::PopClient(SharedPtr<Client>& c)
{
	return _mgr->Pop(c);
}

void Service::Clear()
{
	_mgr->Clear();
}

DWORD Service::DeleteClient(void* invoker)
{
	this->DeleteClient((SOCKIDEN)invoker);
	return 0;
}

void Service::AddClient(const SharedPtr<Client>& c)
{
	_mgr->Insert(c->GetSocketIden(), c);
}

size_t Service::GetSize() const
{
	return _mgr->Size();
}

bool Service::IsExistClient(const std::string& iden) const
{
	std::vector<std::string> flags;
	split(iden, (int)'|', flags);
	if (flags.size() == 2)
	{
		if (flags[0] == _serviceFlag.GetReference())
		{
			return _mgr->Find(LibTools::stoll(iden));
		}
	}

	return false;
}

bool Service::IsServiceFlag(const std::string& iden) const
{
	std::vector<std::string> flags;
	split(iden, (int)'|', flags);
	if (flags.size() == 2)
	{
		if (flags[0] == _serviceFlag.GetReference())
		{
			return true;
		}
	}

	return false;
}

/*SharedPtr<Client> Service::GetClient(const std::string& iden)
{
	std::vector<std::string> flags;
	split(iden, (int)'|', flags);
	if (flags.size() == 2)
	{
		if (flags[0] == _serviceFlag.GetReference())
		{
			CLockGurad lk(&_mgr->_mutexMap);
			std::map<SOCKIDEN, SharedPtr<Client> >::iterator it = _mgr->_mapData.find(LibTools::stoll(flags[1]));
			if (it != _mgr->_mapData.end())
			{
				SharedPtr<Client> rtn = it->second;
				return rtn;
			}
		}
	}

	return SharedPtr<Client>(NullPtr);
}*/

void Service::SetServiceFlag(const std::string& flag)
{
	_serviceFlag.GetReference() = flag;
}

std::string Service::GetServiceFlag() const
{
	return _serviceFlag.GetReference();
}

std::string Service::GetClientIden(Client* c) const
{
	std::string sockId;
	if (c)
	{
#ifdef WIN32
		sockId = STD_MOVE(format_s(32, "%s|%I64d", _serviceFlag.GetReference().c_str(), c->GetSocketIden()));
#elif defined(LINUX)
		sockId = STD_MOVE(format_s(32, "%s|%lld", _serviceFlag.GetReference().c_str(), c->GetSocketIden()));
#endif
	}

	return STD_MOVE(sockId);
}

DEF_END_LIBTOOLS